package com.loyal.loyalerp.basedata.department.service.impl;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.druid.util.StringUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.loyal.loyalerp.basedata.company.mapper.GyCompanyMapper;
import com.loyal.loyalerp.basedata.department.entity.DepartmentNode;
import com.loyal.loyalerp.basedata.department.mapper.DepartmentMapper;
import com.loyal.loyalerp.basedata.department.model.Department;
import com.loyal.loyalerp.basedata.department.model.DepartmentExample;
import com.loyal.loyalerp.basedata.department.model.DepartmentExample.Criteria;
import com.loyal.loyalerp.basedata.department.service.DepartmentService;
import com.loyal.loyalerp.model.GyPerson;
import com.loyal.loyalerp.model.form.GridSearchForm;
import com.loyal.loyalerp.model.vo.GridVO;

@Service
public class DepartmentServiceImpl implements DepartmentService {

	private static final Map<String, String> OPER_MAP = new HashMap<String, String>();
	static {
		OPER_MAP.put("eq", "EqualTo");
		OPER_MAP.put("ne", "NotEqualTo");
		OPER_MAP.put("lt", "LessThan");
		OPER_MAP.put("le", "LessThanOrEqualTo");
		OPER_MAP.put("gt", "GreaterThan");
		OPER_MAP.put("ge", "GreaterThanOrEqualTo");
		OPER_MAP.put("nu", "IsNull");
		OPER_MAP.put("nn", "IsNotNull");
		OPER_MAP.put("in", "Like");
		OPER_MAP.put("ni", "NotLike");
		OPER_MAP.put("bw", "Like");
		OPER_MAP.put("bn", "NotLike");
		OPER_MAP.put("ew", "Like");
		OPER_MAP.put("en", "NotLike");
	}

	@Autowired
	private DepartmentMapper deptMapper;
	@Autowired
	private GyCompanyMapper companyMapper;

	@Override
	public PageInfo<Department> page(Integer pageNum, Integer pageSize) {
		Page<Department> page = PageHelper.startPage(pageNum, pageSize);
		deptMapper.selectByExample(new DepartmentExample());
		return new PageInfo<Department>(page);
	}

	@Override
	public List<Department> list() {
		return deptMapper.selectByExample(null);
	}

	@Override
	public GridVO<Department> gridSearch(GridSearchForm form) throws IllegalAccessException, IllegalArgumentException,
			InvocationTargetException, NoSuchMethodException, SecurityException, NoSuchFieldException {
		DepartmentExample ep = new DepartmentExample();
		if (!StringUtils.isEmpty(form.getSidx())) {
			ep.setOrderByClause("`" + form.getSidx() + "` " + form.getSord());
		}
		Criteria ct = ep.createCriteria();
		if (form.get_search()) {
			if ("in".equals(form.getSearchOper()) || "ni".equals(form.getSearchOper())) {
				form.setSearchString("%" + form.getSearchString() + "%");
			} else if ("bw".equals(form.getSearchOper()) || "bn".equals(form.getSearchOper())) {
				form.setSearchString(form.getSearchString() + "%");
			} else if ("ew".equals(form.getSearchOper()) || "en".equals(form.getSearchOper())) {
				form.setSearchString("%" + form.getSearchString());
			}
			String expectMethodName = "and" + form.getSearchField() + OPER_MAP.get(form.getSearchOper());
			System.out.println(expectMethodName);
			Method[] methods = ct.getClass().getDeclaredMethods();
			for (Method method : methods) {
				if (method.getName().toLowerCase().equals(expectMethodName.toLowerCase())
						&& method.getParameterTypes().length == 1) {
					String paramType = method.getParameterTypes()[0].getSimpleName();
					Object res = null;
					if ("String".equals(paramType)) {
						res = form.getSearchString();
					} else {
						Method toTargetClassMethod = StringUtils.class.getMethod("stringTo" + paramType, String.class);
						res = toTargetClassMethod.invoke(StringUtils.class, form.getSearchString());
					}
					method.invoke(ct, res);
					break;
				}
			}

		}
		int rows = form.getRows();
		if (rows <= 0) {
			rows = (int) deptMapper.countByExample(ep);
		}

		Page<Department> page = PageHelper.startPage(form.getPage(), rows);
		deptMapper.selectByExample(ep);
		PageInfo<Department> info = new PageInfo<Department>(page);
		return GridVO.fromPageInfo(info);
	}

	@Override
	public boolean cud(String oper, Department department) {

		if (oper.equals("add")) {
			deptMapper.insertSelective(department);
		} else if (oper.equals("del")) {
			deptMapper.deleteByPrimaryKey(department.getId());
		} else if (oper.equals("edit")) {
			deptMapper.updateByPrimaryKeySelective(department);
		}

		return true;
	}

	@Override
	public DepartmentNode tree(Integer id) {
		DepartmentNode node = new DepartmentNode();
		if (id <= 0) {
			id = 0;
			node.setId(id);
			node.setDeptName("root");
			node.setDeptCode("0");
		} else {
			Department dept = deptMapper.selectByPrimaryKey(id);
			node.setId(dept.getId());
			node.setDeptCode(dept.getDeptCode());
			node.setDeptName(dept.getDeptName());
		}
		List<Department> deptChilds = deptMapper.getChildsById(id);
		if (!(deptChilds == null || deptChilds.isEmpty())) {

			List<DepartmentNode> nodeChilds = new ArrayList<DepartmentNode>();
			for (Department ldept : deptChilds) {
				nodeChilds.add(tree(ldept.getId()));
			}
			node.setChilds(nodeChilds);
		}
		return node;
	}

	@Override
	public List<Department> getChildsById(Integer id) {
		return deptMapper.getChildsById(id);
	}

	@Override
	public List<GyPerson> getPersonsById(Integer id) {
		return deptMapper.getPersonsById(id);
	}

	@Override
	public List<GyPerson> getPersonsByIds(List<Integer> ids) {
		return deptMapper.getPersonsByIds(ids);
	}

	@Override
	public List<GyPerson> getPersonsByDepartments(List<Department> departments) {
		return deptMapper.getPersonsByDepartments(departments);
	}

	@Override
	public long countByExample(DepartmentExample example) {
		return deptMapper.countByExample(example);
	}

	@Override
	public int deleteByCompanyId(Integer id) {
		return deptMapper.deleteByCompanyId(id);
	}

	@Override
	public int deleteByExample(DepartmentExample example) {
		return deptMapper.deleteByExample(example);
	}

	@Override
	public int deleteByPrimaryKey(Integer id) {
		return deptMapper.deleteByPrimaryKey(id);
	}

	@Override
	public int insert(Department record) {
		return deptMapper.insert(record);
	}

	@Override
	public int insertSelective(Department record) {
		return deptMapper.insertSelective(record);
	}

	@Override
	public List<Department> selectByExample(DepartmentExample example) {
		return deptMapper.selectByExample(example);
	}

	@Override
	public Department selectByPrimaryKey(Integer id) {
		return deptMapper.selectByPrimaryKey(id);
	}

	@Override
	public int updateByExampleSelective(Department record, DepartmentExample example) {
		return deptMapper.updateByExampleSelective(record, example);
	}

	@Override
	public int updateByExample(Department record, DepartmentExample example) {
		return deptMapper.updateByExample(record, example);
	}

	@Override
	public int updateByPrimaryKeySelective(Department record) {
		return deptMapper.updateByPrimaryKeySelective(record);
	}

	@Override
	public int updateByPrimaryKey(Department record) {
		return deptMapper.updateByPrimaryKey(record);
	}

	@Override
	public List<Department> selectByCompanyId(Integer id) {
		return deptMapper.selectByCompanyId(id);
	}

	@Override
	public Department selectByDeptname(String deptname) {
		return deptMapper.selectByDeptname(deptname);
	}

}
